/*
 * TCPMessenger.cpp
 *
 *  Created on: 28.03.2011
 *      Author: niea
 */

#include "TCPMessenger.h"
#include "../common/Utils.hpp"

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

namespace efs
{

TCPMessenger::TCPMessenger(ClientEntryList *client_list)
	: m_client_list(client_list)
{

}

TCPMessenger::~TCPMessenger()
{
}

void TCPMessenger::sendMessages(std::string const &msg)
{
	pantheios::log_DEBUG("[TCPMessenger]: sending messages");
	std::vector<ClientEntry> entry_list = m_client_list->getList();
	std::vector<ClientEntry>::iterator it = entry_list.begin();

	for (; it != entry_list.end(); ++it)
	{
		//usleep(100);
		if (sendMessage(*it, msg) != 0)
		{
			pantheios::log_DEBUG("[TCPMessenger]: erasing entry:");
			m_client_list->removeEntry(*it);
		}
	}
}

int TCPMessenger::sendMessage(ClientEntry & client, std::string const &msg)
{
	pantheios::log_DEBUG("[TCPMessenger]: sending message, IP=" + client.ip
			+ " port=" + intToStr(client.tcp_port));
	int sock;
	struct sockaddr_in addr;

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
	{
		pantheios::log_ERROR("[TCPMessenger]: socket");
		return -1;
    }

	addr.sin_family = AF_INET;
	addr.sin_port = htons(client.tcp_port);
	addr.sin_addr.s_addr = inet_addr(client.ip.c_str());
	if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		pantheios::log_ERROR("[TCPMessenger]: connect");
		return -1;
	}

	//TODO:
	//sleep(1);
	pantheios::log_DEBUG("[TCPMessenger]: sending data, length = " + intToStr(msg.length() + 1));
	//send(sock, msg.c_str(), msg.length() + 1, 0);
	sendAll(sock, msg);
	//sleep(1);

	close(sock);
	pantheios::log_DEBUG("[TCPMessenger]: sending OK");

	return 0;
}

int TCPMessenger::sendAll(int sock, std::string const &msg)
{
	int len = msg.length() + 1;
	int total = 0;
	int n;

	while(total < len)
	{
		n = send(sock, (void*)(&msg.c_str()[total]), len-total, 0);
		if(n == -1)
		{
			break;
		}
		total += n;
	}

	return (n==-1 ? -1 : total);

}
}
